﻿Imports System.Text.RegularExpressions
Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
Imports System.Threading.Tasks

Module Program
    Private m_DoClose As Boolean = False

    Private m_TEMPIDs As New Dictionary(Of String, UtilisateurPreco)
    Private m_Utilisateurs As New Dictionary(Of String, Utilisateur)

    Private m_SalonsPermanents As New Dictionary(Of String, Salon)
    Private m_SalonsPublics As New Dictionary(Of String, Salon)
    Private m_SalonsPrivates As New Dictionary(Of String, Salon)

    Private m_ProbComportement As New Dictionary(Of String, Integer)
    Private m_ProbComportementLastReport As New Dictionary(Of String, Date)

    Private m_ComportementFlushMini As Integer = 3
    Private m_ComportementFlashInterval As New TimeSpan(0, 0, 30)

    Private m_Ignores As New Dictionary(Of String, List(Of String))

    Private connectionWaitHandle As New AutoResetEvent(False)

    'Private mysql As New MySQL()

    Private Sub SendAll(data() As String)
        'Parallel.ForEach(Of Utilisateur)(m_Utilisateurs.Values, Sub(u) u.SendData(data))

        For Each u In m_Utilisateurs.Values
            u.SendData(data)
        Next
    End Sub'

#Region "Proto help"
    'part : 85|1|id|0|pseudo|0|26|1|ville
    'arrive : 85|0|id|0|pseudo|0|26|1|ville

    'demande des salons publics : 90


    'changement statut : 84|status

    'occupé : 26|64
    'plus occupé : 26|0

    'demande invisible : 26|68
    'plus invisible : 26|64

    'refresh connectés : 199

    'corbeille salon public : 255|nom_salon

    'rejoindre/créé salon public : 40|nom_salon|0
    'rejoindre/créé salon privé  : 40|nom_salon|1

    '    // demande ignore : 18|0|pseudo:0
    '// demande designore : 18|1|pseudo:0
    '// demande superignore : 16|0|pseudo:0
    '// kick : 555|pseudo:0
    '// prob comportement : 550
    '// no pv : 26|2 \n 19|0|id1|id2
    '// back no pv : 26|0 \n 19|-1
    '// recherche par pseudo : 56|keywork|ageIndex|sexIndex
    '// recherche par ville : 58|keywork|ageIndex|sexIndex
    '// 26 :
    '//    2 : no pv
    '//    4 : invisible
    '//    8 :
    '//    16:
    '//    32:
    '//    64: occupé
#End Region

    Private Sub SendStream(stream As NetworkStream, data As String)

    End Sub

    Private m_Welcome As String = "JuneLive v0.6 beta By Nicolas Quenault (nquenault@gmail.com)"
    Private Sub HandleAsyncConnection(result As IAsyncResult)
        Dim listener = DirectCast(result.AsyncState, TcpListener)
        Dim client As TcpClient = listener.EndAcceptTcpClient(result)
        Dim user As Utilisateur = Nothing
        Dim lock As New Object()
        Dim pongResponded As Boolean = False
        Dim acceptIgnore As Boolean = False

        connectionWaitHandle.Set()

        Dim stream = client.GetStream()

        Dim cep As IPEndPoint = client.Client.RemoteEndPoint
        Console.WriteLine("connected:" & cep.Address.ToString())
        'Logs.Access("connected:" & cep.Address.ToString())

        Dim sendBytes As [Byte]() = Encoding.UTF8.GetBytes("100" & vbTab & m_Welcome & Chr(10))
        Try
            Console.WriteLine("SENDING=[100|" & m_Welcome & "]")
            'Logs.Access("SENDING=[100|" & m_Welcome & "]")
            stream.Write(sendBytes, 0, sendBytes.Length)
        Catch ex As Exception
        End Try

        Dim timer As New Timers.Timer(New TimeSpan(0, 5, 0).TotalMilliseconds) With {.Enabled = False, .AutoReset = True}
        Dim timerOut As New Timers.Timer(New TimeSpan(0, 1, 0).TotalMilliseconds) With {.Enabled = False, .AutoReset = False}
        Dim timerAfk As New Timers.Timer(New TimeSpan(0, 4, 0).TotalMilliseconds) With {.Enabled = False, .AutoReset = False}

        AddHandler timerAfk.Elapsed,
            Sub()
                timerAfk.Stop()
                user.IsBusy = True

                user.SendData({26, user.State})

                If Not user.IsInvisible Then
                    user.SalonCourant.SendAll({85, 0, user.Id, user.UserLevel, user.Pseudo, user.State, user.Age.ToString, user.Sexe, user.Ville, ""})
                End If
            End Sub

        AddHandler timerOut.Elapsed,
            Sub()
                timerOut.Stop()
                If pongResponded Then Exit Sub

                If Not IsNothing(user) Then
                    Console.WriteLine("PING TIMEOUT(" & user.Pseudo & ")")
                    Logs.Access("PING TIMEOUT(" & user.Pseudo & ")")
                End If

                timer.Stop()
                stream.Close()
                client.Client.Close()
            End Sub

        AddHandler timer.Elapsed,
            Sub(sender As Object, e As Timers.ElapsedEventArgs)
                Dim sendBytest As [Byte]() = Encoding.UTF8.GetBytes("667" & vbTab & Chr(10))
                Try
                    'Console.WriteLine("SENDING=[667|]")
                    'Logs.Access("SENDING=[667|]")
                    pongResponded = False
                    timerOut.Stop()
                    timerOut.Start()
                    stream.Write(sendBytest, 0, sendBytest.Length)
                Catch ex As Exception
                End Try
            End Sub
        timer.Start()

        While client.Connected
            Dim data = New [Byte](256) {}
            Dim responseData As [String] = [String].Empty

            Dim bytes As Int32 = 0
            Try
                bytes = stream.Read(data, 0, data.Length)

                If bytes = 0 Then
                    stream.Close()
                    client.Client.Close()
                    Exit While
                End If

                responseData = System.Text.Encoding.UTF8.GetString(data, 0, bytes).Trim
            Catch
                stream.Close()
                client.Client.Close()
                Exit While
            End Try

            ThreadPool.QueueUserWorkItem(
                Sub()
                    If Not String.IsNullOrEmpty(responseData) Then
                        Dim lines = responseData.Split(Chr(10))

                        For Each line In lines
                            If String.IsNullOrEmpty(line) Then Continue For

                            Dim dline = "RECEIVED"

                            If Not IsNothing(user) Then
                                dline &= "(" & user.Pseudo & ")"
                            End If
                            dline &= "=[" & line.Replace(vbTab, "|") & "]"

                            Try
                                'IO.File.AppendAllText("network.log", "[" & DateTime.Now.ToString() & "] /* RECEIVED */ " & line & Chr(10))
                            Catch
                            End Try

                            Dim inputs = line.Split(vbTab)

                            If inputs.Count >= 1 AndAlso Val(inputs(0)) <> 667 Then
                                Console.WriteLine(dline)
                                Logs.Access(dline)

                                If Not IsNothing(user) AndAlso user.IsBusy AndAlso Val(inputs(0)) = 70 Then
                                    user.IsBusy = False
                                    user.SendData({26, user.State})

                                    If user.IsBusy AndAlso Not user.IsInvisible Then
                                        user.SalonCourant.SendAll({85, 0, user.Id, user.UserLevel, user.Pseudo, user.State, user.Age.ToString, user.Sexe, user.Ville, ""})
                                    End If
                                End If

                                If Not IsNothing(user) AndAlso Val(inputs(0)) = 70 Then
                                    'timerAfk.Stop()
                                    'timerAfk.Start()
                                End If

                                'If Not IsNothing(user) Then
                                '    '    If user.IsBusy AndAlso Not user.IsInvisible Then
                                '    '        user.SalonCourant.SendAll({85, 0, user.Id, user.UserLevel, user.Pseudo, user.State, user.Age.ToString, user.Sexe, user.Ville, ""})
                                '    '    End If
                                'End If
                            End If

                            Try
                                If IsNothing(user) AndAlso Not inputs(0) = "0" Then
                                    stream.Close()
                                    client.Client.Close()
                                    Exit Sub
                                End If

                                Select Case Val(inputs(0))
                                    Case 0 ' identification
                                        Dim tempid = inputs(2)

                                        Dim preco = DatabaseIO.GetUtilisateurPrecoParTempid(tempid)

                                        If IsNothing(preco) OrElse String.IsNullOrEmpty(preco.Pseudo) Then
                                            client.Client.Close()
                                            Exit Sub
                                        End If

                                        Console.WriteLine("[preco] pseudo=[" & preco.Pseudo & "]")
                                        Logs.Access("[preco] pseudo=[" & preco.Pseudo & "]")

                                        user = New Utilisateur(client, preco)

                                        m_Utilisateurs.Add(user.Id, user)

                                        user.SendData({0, user.Id, inputs(1), user.State, user.Pseudo}) ' 197
                                    Case 16 ' super ignorer
                                        '16|0|pseudo:0

                                        If user.UserLevel = UserLevel.Utilisateur Or inputs.Length = 1 Then Exit Sub

                                        Dim pseudo = inputs(2)
                                        pseudo = pseudo.Substring(0, pseudo.IndexOf(":"))
                                    Case 18 ' (des)ignorage
                                        If Not acceptIgnore Then Exit Sub

                                        Dim ignorage As Boolean = (inputs(1) = "0")
                                        Dim pseudo = inputs(2)
                                        pseudo = pseudo.Substring(0, pseudo.IndexOf(":"))

                                        If Not m_Ignores.ContainsKey(user.Id) Then
                                            m_Ignores.Add(user.Id, New List(Of String))
                                        End If

                                        For Each u In m_Utilisateurs.Values
                                            If Not u.Pseudo = pseudo Then Continue For
                                            If Not u.UserLevel = UserLevel.Utilisateur Then
                                                u.SendData({76, 6, user.Id, user.Pseudo})
                                                Exit For
                                            End If

                                            If ignorage Then
                                                If Not m_Ignores(user.Id).Contains(inputs(2)) Then
                                                    m_Ignores(user.Id).Add(inputs(2))
                                                End If

                                                u.SendData({76, 6, user.Id, user.Pseudo})
                                            Else
                                                If m_Ignores(user.Id).Contains(inputs(2)) Then
                                                    m_Ignores(user.Id).Remove(inputs(2))
                                                End If
                                            End If

                                            'Dim fdata = Microsoft.VisualBasic.Split("18|-1|" & Microsoft.VisualBasic.Join(m_Ignores(user.Id).ToArray, "|"), "|")
                                            Dim fdata As New List(Of String)
                                            fdata.AddRange({18, -1})
                                            fdata.AddRange(m_Ignores(user.Id))

                                            user.SendData(fdata.ToArray)

                                            Exit For
                                        Next
                                    Case 20 ' rejoindre salon (après connection)
                                        Dim nomSalon = inputs(1)

                                        If m_SalonsPermanents.ContainsKey(nomSalon) Then
                                            user.SalonCourant = m_SalonsPermanents(nomSalon)
                                        ElseIf m_SalonsPublics.ContainsKey(nomSalon) Then
                                            user.SalonCourant = m_SalonsPublics(nomSalon)
                                        Else
                                            m_SalonsPublics.Add(nomSalon, New Salon(nomSalon, user.Pseudo))
                                            user.SalonCourant = m_SalonsPublics(nomSalon)
                                        End If

                                        If Not user.IsInvisible Then
                                            user.SalonCourant.SendAll({85, 0, user.Id, user.UserLevel, user.Pseudo, user.State, user.Age.ToString, user.Sexe, user.Ville, ""})
                                        End If

                                        'user.SalonCourant.SendAll("85|0|" & user.Id & "|" & user.UserLevel & "|" & user.Pseudo & "|0|" & user.Age.ToString & "|" & user.Sexe & "|" & user.Ville & "|")
                                        user.SalonCourant.Utilisateurs.Add(user)

                                        user.SendData({20, 0, inputs(1), "?", user.SalonCourant.CreatedBy, ""})
                                        acceptIgnore = False
                                        user.SalonCourant.SendHistorique(user)
                                        Threading.Thread.Sleep(2000)
                                        acceptIgnore = True
                                    Case 26
                                        Dim bOccupe = user.IsBusy
                                        Dim bInvisible = user.IsInvisible

                                        user.State = Val(inputs(1))
                                        user.SendData({26, user.State})

                                        If Not user.IsBusy = bOccupe OrElse Not user.IsInvisible = bInvisible Then
                                            If user.IsInvisible Then
                                                user.SalonCourant.SendAll({85, 1, user.Id, user.UserLevel, user.Pseudo, user.State, user.Age.ToString, user.Sexe, user.Ville, ""})
                                            End If

                                            If Not user.IsInvisible Then
                                                user.SalonCourant.SendAll({85, 0, user.Id, user.UserLevel, user.Pseudo, user.State, user.Age.ToString, user.Sexe, user.Ville, ""})
                                            End If
                                        End If
                                    Case 40 ' changement de salon (depuis un salon)
                                        Dim nomSalon = inputs(1)
                                        Dim salonPublic As Boolean = (Val(inputs(2)) = 0)

                                        user.SalonCourant.Utilisateurs.Remove(user)

                                        If user.SalonCourant.UsersCount = 0 Then
                                            If m_SalonsPublics.ContainsKey(user.SalonCourant.Nom) Then
                                                m_SalonsPublics.Remove(user.SalonCourant.Nom)
                                            ElseIf m_SalonsPrivates.ContainsKey(user.SalonCourant.Nom) Then
                                                m_SalonsPrivates.Remove(user.SalonCourant.Nom)
                                            End If
                                        End If

                                        user.SalonCourant.SendAll({85, 1, user.Id, user.UserLevel, user.Pseudo, user.State, user.Age.ToString, user.Sexe, user.Ville, ""})

                                        If m_SalonsPermanents.ContainsKey(nomSalon) Then
                                            user.SalonCourant = m_SalonsPermanents(nomSalon)
                                        ElseIf m_SalonsPublics.ContainsKey(nomSalon) Then
                                            user.SalonCourant = m_SalonsPublics(nomSalon)
                                        ElseIf salonPublic Then
                                            m_SalonsPublics.Add(nomSalon, New Salon(nomSalon, user.Pseudo))
                                            user.SalonCourant = m_SalonsPublics(nomSalon)
                                        Else
                                            m_SalonsPrivates.Add(nomSalon, New Salon(nomSalon, user.Pseudo))
                                            user.SalonCourant = m_SalonsPrivates(nomSalon)
                                        End If

                                        If Not user.IsInvisible Then
                                            user.SalonCourant.SendAll({85, 0, user.Id, user.UserLevel, user.Pseudo, user.State, user.Age.ToString, user.Sexe, user.Ville, ""})
                                        End If
                                        user.SalonCourant.Utilisateurs.Add(user)

                                        user.SendData({40, 0, inputs(1), "?", user.SalonCourant.CreatedBy, ""})
                                        acceptIgnore = False
                                        user.SalonCourant.SendHistorique(user)
                                        Threading.Thread.Sleep(2000)
                                        acceptIgnore = True
                                    Case 56, 58 ' recherche par pseudo
                                        Dim search = inputs(1)
                                        Dim ageIndex = Val(inputs(2))
                                        Dim sexeIndex = Val(inputs(3))
                                        Dim rechercheParPseudo = (Val(inputs(0)) = 56)

                                        'Indiff\u00e9rent*5-10 ans*10-15 ans*15-20 ans*20-25 ans*25-30 ans*30-40 ans*40-50 ans*50-60 ans*60-70 ans*70 et plus*Autres...
                                        'Indiff\u00e9rent*Femme*Homme*Je ne sais pas

                                        Dim list As New List(Of String)
                                        list.AddRange({inputs(0), ageIndex & ":" & sexeIndex})

                                        Dim noone As Boolean = True
                                        For Each u In m_Utilisateurs.Values
                                            If user.UserLevel < u.UserLevel Then Continue For
                                            'If Not u.UserLevel < UserLevel.Utilisateur Then Continue For

                                            Select Case ageIndex
                                                Case 1
                                                    If u.Age < 5 OrElse u.Age > 10 Then Continue For
                                                Case 2
                                                    If u.Age < 10 OrElse u.Age > 15 Then Continue For
                                                Case 3
                                                    If u.Age < 15 OrElse u.Age > 20 Then Continue For
                                                Case 4
                                                    If u.Age < 20 OrElse u.Age > 25 Then Continue For
                                                Case 5
                                                    If u.Age < 25 OrElse u.Age > 30 Then Continue For
                                                Case 6
                                                    If u.Age < 30 OrElse u.Age > 40 Then Continue For
                                                Case 7
                                                    If u.Age < 40 OrElse u.Age > 50 Then Continue For
                                                Case 8
                                                    If u.Age < 50 OrElse u.Age > 60 Then Continue For
                                                Case 9
                                                    If u.Age < 60 OrElse u.Age > 70 Then Continue For
                                                Case 10
                                                    If u.Age < 70 Then Continue For
                                            End Select

                                            Select Case sexeIndex
                                                Case 0
                                                    If Not u.Sexe = Sexe.Femme Then Continue For
                                                Case 1
                                                    If Not u.Sexe = Sexe.Homme Then Continue For
                                                Case -1
                                                    If Not u.Sexe = Sexe.Inconnu Then Continue For
                                            End Select

                                            If (rechercheParPseudo AndAlso u.Pseudo.Substring(0, search.Length).ToLower() = search.ToLower()) OrElse
                                                (Not rechercheParPseudo AndAlso u.Ville.Substring(0, search.Length).ToLower() = search.ToLower()) Then
                                                '4 salon
                                                '1 privé
                                                Dim codeSalon = "4"
                                                Dim nomSalon = u.SalonCourant.Nom

                                                If m_SalonsPrivates.ContainsKey(u.SalonCourant.Nom) Then
                                                    codeSalon = "1"
                                                    nomSalon = "?"
                                                End If

                                                list.AddRange({u.Id, u.Pseudo, u.UserLevel, u.Age, u.Sexe, u.Ville, nomSalon, codeSalon})
                                                noone = False
                                            End If
                                        Next

                                        If Not noone Then
                                            list(1) &= ":-2"
                                        End If

                                        user.SendData(list.ToArray)
                                    Case 70 ' dire
                                        If user.UserLevel > UserLevel.Utilisateur Then
                                            Dim msg = inputs(1).Substring(4)

                                            If msg.StartsWith("!proto ") Then
                                                Dim inject = msg.Substring("!proto ".Length)
                                                Dim idata = Microsoft.VisualBasic.Split(inject, "|")
                                                user.SalonCourant.SendAll(idata)
                                            ElseIf msg.StartsWith("!infosalon ") Then
                                                user.SalonCourant.SendAll({77, "0502" & msg.Substring("!infosalon ".Length), ""})
                                            ElseIf msg.StartsWith("!infoserver ") Then
                                                SendAll({77, "0502" & msg.Substring("!infoserver ".Length), ""})
                                            Else
                                                user.SalonCourant.SendAll({70, user.Id, user.State, user.Pseudo, inputs(1)})
                                            End If
                                        Else
                                            user.SalonCourant.SendAll({70, user.Id, user.State, user.Pseudo, inputs(1)})
                                        End If

                                        'user.SendData({332, 1, "pseudo2", "0"}) ' ami déco
                                        'user.SendData({332, 1, "nquenault", "1"})
                                        'user.SendData({332, 1, "jetrude", "2"})

                                        'user.SendData({332, 0, "1" & user.Id, "Nk le RouGe2", 64, 26, 1, "Tours", "statut"})
                                    Case 72 ' dire pv
                                        Dim id = inputs(1)
                                        Dim phrase = inputs(2)

                                        If m_Utilisateurs.ContainsKey(id) Then
                                            With m_Utilisateurs(id)
                                                If .IsNoPV Then
                                                    user.SendData({75, .Id, .Pseudo})
                                                    Exit Sub
                                                End If

                                                .SendData({72, user.Id, user.State, user.Pseudo, phrase})

                                                If .IsBusy Then
                                                    user.SendData({79, .Id, .State, .Pseudo, phrase, .Status})
                                                Else
                                                    user.SendData({73, .Id, .State, .Pseudo, phrase})
                                                End If
                                            End With
                                        Else
                                            user.SendData({74, id})
                                        End If
                                    Case 82 ' info user
                                        Dim id = inputs(1)

                                        If m_Utilisateurs.ContainsKey(id) Then
                                            With m_Utilisateurs(id)
                                                user.SendData({82, .Id, .UserLevel, .Age.ToString, .Sexe, .Ville, ""})
                                            End With
                                        End If
                                    Case 84
                                        user.Status = If(inputs.Length > 1, inputs(1), "en ligne")
                                        user.SendData({84, user.Status})
                                    Case 85
                                        Dim list As New List(Of String)
                                        list.AddRange({85, -1})

                                        For Each u In user.SalonCourant.Utilisateurs
                                            If Not u.IsInvisible Then
                                                list.AddRange({u.Id, u.UserLevel, u.Pseudo, u.State, u.Age.ToString, u.Sexe, u.Ville})
                                            End If
                                        Next

                                        user.SendData(list.ToArray)
                                    Case 90 ' demande salons publics
                                        Dim list As New List(Of String)
                                        list.AddRange({90})

                                        For Each salon In m_SalonsPublics.Values
                                            list.AddRange({salon.Nom & "#0", "?", salon.CreatedBy, salon.UsersCount})
                                        Next
                                        user.SendData(list.ToArray)

                                        'user.SendData({330, -1, "bite.en.feu:1<Nk>"})
                                        'user.SendData({332, -1,
                                        '    user.Id, user.Pseudo, user.State, user.Age, user.Sexe, user.Ville, user.Status,
                                        '    "4665:692:42156:0", "alias", 0, 26, 0, "Tours", "statut",
                                        '    "5125:543:64461:1", "bite.en.feu", 0, 26, 1, "Tours", "DTC"
                                        '})
                                    Case 94 ' demande salon permanents
                                        Dim list As New List(Of String)
                                        list.AddRange({94})

                                        For Each salon In m_SalonsPermanents.Values
                                            list.AddRange({salon.Nom & "#0", "?", salon.CreatedBy, salon.UsersCount})
                                        Next
                                        user.SendData(list.ToArray)

                                    Case 199 ' demande nbr connectés
                                        user.SendData({199, m_Utilisateurs.Count})
                                    Case 255 ' corbeille salon
                                        If user.UserLevel = UserLevel.Utilisateur Then Exit Sub

                                        Dim nomSalon = inputs(1)
                                        Dim salon As Salon = Nothing

                                        If m_SalonsPermanents.ContainsKey(nomSalon) Then Exit Sub

                                        If m_SalonsPrivates.ContainsKey(nomSalon) Then
                                            salon = m_SalonsPrivates(nomSalon)
                                        ElseIf m_SalonsPublics.ContainsKey(nomSalon) Then
                                            salon = m_SalonsPublics(nomSalon)
                                        End If

                                        If IsNothing(salon) Then Exit Sub

                                        For Each u In salon.Utilisateurs
                                            If Not u.UserLevel = UserLevel.Utilisateur Then Continue For
                                            u.SendData({555, u.Id})
                                            u.SalonCourant.Utilisateurs.Remove(u)
                                            'u.SalonCourant.SendAll({76, 5, u.Id, u.Pseudo, user.Id, user.Pseudo})
                                            u.Disconnect()
                                        Next

                                        If m_SalonsPrivates.ContainsKey(nomSalon) Then
                                            m_SalonsPrivates.Remove(nomSalon)
                                        ElseIf m_SalonsPublics.ContainsKey(nomSalon) Then
                                            m_SalonsPublics.Remove(nomSalon)
                                        End If
                                    Case 550 ' prob de comportement
                                        Dim salon = user.SalonCourant.Nom

                                        If Not m_ProbComportement.ContainsKey(salon) Then
                                            m_ProbComportement.Add(salon, 1)
                                            'm_ProbComportementLastReport.Add(salon, DateTime.Now)
                                        Else
                                            m_ProbComportement(salon) += 1
                                        End If

                                        If Not m_ProbComportement(salon) >= m_ComportementFlushMini Then Exit Sub

                                        Dim count = m_ProbComportement(salon)
                                        m_ProbComportement(salon) = 0

                                        For Each u In m_Utilisateurs.Values
                                            If u.UserLevel = UserLevel.Utilisateur Then Continue For
                                            u.SendData({550, salon, count})
                                        Next
                                    Case 555 ' kick
                                        If user.UserLevel = UserLevel.Utilisateur Then Exit Sub

                                        Dim pseudo = inputs(1)
                                        pseudo = pseudo.Substring(0, pseudo.IndexOf(":"))

                                        For Each u In m_Utilisateurs.Values
                                            If u.Pseudo = pseudo Then
                                                If user.UserLevel < u.UserLevel Then Exit Sub

                                                u.SendData({555, u.Id})
                                                u.SalonCourant.Utilisateurs.Remove(u)
                                                u.SalonCourant.SendAll({76, 5, u.Id, u.Pseudo, user.Id, user.Pseudo})
                                                u.Disconnect()

                                                Exit For
                                            End If
                                        Next
                                    Case 667 ' PONG
                                        pongResponded = True
                                End Select
                            Catch ex As Exception
                                Debug.Print("Program Exception (" & ex.Message & ")")
                                Logs.Error("Program Exception (" & ex.Message & ") dline=[" & dline & "]")
                            End Try
                        Next
                    End If
                End Sub
            )
        End While

        timer.Stop()
        timerOut.Stop()

        If Not IsNothing(user) Then
            Console.WriteLine("LEAVING(" & user.Pseudo & ")")
            Logs.Access("LEAVING(" & user.Pseudo & ")")
            If m_Utilisateurs.ContainsKey(user.Id) Then
                m_Utilisateurs.Remove(user.Id)
            End If

            Try
                If user.SalonCourant.Utilisateurs.Contains(user) Then
                    user.SalonCourant.Utilisateurs.Remove(user)
                End If
            Catch
            End Try
            Try
                user.SalonCourant.SendAll({85, 1, user.Id, user.UserLevel, user.Pseudo, user.State, user.Age.ToString, user.Sexe, user.Ville, ""})
            Catch
            End Try
        End If
    End Sub

    Sub Main()
        InitSalons()

        'With m_TEMPIDs
        '    .Add("441c2ee2394ccc418d0f412634979f97", New UtilisateurPreco(
        '         "nk",
        '         UserLevel.Utilisateur,
        '         26,
        '         Sexe.Homme,
        '         "Tours"
        '    ))
        '    .Add("441c2ee2394ccc418d0f412634979f98", New UtilisateurPreco(
        '         "#Nk",
        '         UserLevel.Administrateur,
        '         26,
        '         Sexe.Homme,
        '         "Tours"
        '    ))
        '    .Add("89ds8d9gs614s89dg769d7gg", New UtilisateurPreco(
        '         "alex", UserLevel.Utilisateur, 24, Sexe.Homme, "Tours"
        '    ))
        '    .Add("e98t7s32dg1sd5g186hjjlosd", New UtilisateurPreco(
        '         "jean.francois", UserLevel.Utilisateur, 30, Sexe.Homme, "Tours"
        '    ))
        'End With

        Dim listener As New TcpListener(IPAddress.Any, 4500)
        listener.Start()

        While True
            Dim result As IAsyncResult = listener.BeginAcceptTcpClient(AddressOf HandleAsyncConnection, listener)
            connectionWaitHandle.WaitOne()
        End While

        Console.WriteLine(ControlChars.Cr + "Hit enter to continue....")
        Console.Read()
    End Sub

    Sub InitSalons()
        For Each salon In {
            New Salon("Informatique"),
            New Salon("10 - 15 ans"),
            New Salon("15 - 20 ans"),
            New Salon("20 - 25 ans"),
            New Salon("25 - 30 ans"),
            New Salon("30 - 35 ans"),
            New Salon("35 - 40 ans"),
            New Salon("40 - 45 ans"),
            New Salon("45 - 50 ans"),
            New Salon("Twitter"),
            New Salon("Facebook")
        }
            m_SalonsPermanents.Add(salon.Nom, salon)
        Next

        'For Each salon In {
        '    New Salon("Politique fiction"),
        '    New Salon("<<< H@ckErZ >>>")
        '}
        '    m_SalonsPublics.Add(salon.Nom, salon)
        'Next
    End Sub
End Module
